package com.eonmind.ai.core.video.schedule;

import cn.hutool.core.net.url.UrlBuilder;
import com.eonmind.ai.core.video.platform.enums.AiVideoPlatformEnum;
import com.eonmind.ai.core.video.platform.pixverse.PixVerseService;
import com.eonmind.ai.core.video.platform.pixverse.model.PixverseTaskQueryRes;
import com.eonmind.ai.mapper.AiVideoMapper;
import com.eonmind.ai.service.impl.AiVideoService;
import com.eonmind.common.contract.constants.ai.AIVideoPlatformApiConstant;
import com.eonmind.common.contract.enums.ai.AiVideoStatusEnum;
import com.eonmind.common.contract.enums.oss.OssUploadEnum;
import com.eonmind.common.contract.oss.OssUtil;
import com.eonmind.common.contract.timer.Timer;
import com.eonmind.common.provider.entity.ai.AiVideo;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import java.io.InputStream;
import java.net.URL;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * 视频任务同步
 */
@Slf4j
@Component
public class VideoTaskSyncSchedule {
    @Resource(name = "aiDefaultTaskExecutor")
    private ThreadPoolTaskExecutor taskExecutor;
    @Resource
    private AiVideoService aiVideoService;
    @Resource
    private AiVideoMapper aiVideoMapper;
    @Resource
    private PixVerseService pixverseService;
    @Resource
    private RedissonClient redissonClient;
    @Resource
    private OssUtil ossUtil;

    private static final String syncTaskKey = "sync:video";

    @Scheduled(fixedDelay = 1000 * 5)
    public void syncVideoTask() {
        // 获取锁
        RLock lock = redissonClient.getLock(syncTaskKey);
        boolean success = lock.tryLock();
        if (!success) {
            log.debug("当前视频任务同步被抢占，放弃执行");
            return;
        }
        // 查询所有的视频任务
        List<AiVideo> aiVideos = aiVideoMapper.selectAllSyncData();
        log.debug("当前视频任务同步开始，共{}个任务", aiVideos.size());
        CountDownLatch countDownLatch = new CountDownLatch(aiVideos.size());
        try {
            for (AiVideo aiVideo : aiVideos) {
                taskExecutor.execute(() -> {
                    Integer platformId = aiVideo.getPlatformId();
                    AiVideoPlatformEnum byCode = AiVideoPlatformEnum.getByCode(platformId);
                    switch (byCode) {
                        case PIXVERSE:
                            syncPixverseTask(countDownLatch, aiVideo);
                            break;
                        default:
                            break;
                    }
                });
            }
        } catch (Exception e) {
            log.debug("同步任务失败：{}", new Date(), e);
        } finally {
            try {
                countDownLatch.await();
            } catch (Exception e) {
                log.error("同步任务失败：{}", new Date(), e);
            } finally {
                lock.unlock();
            }
        }

    }

    private void syncPixverseTask(CountDownLatch countDownLatch, AiVideo aiVideo) {
        try {
            Runnable task = () -> {
                try {
                    PixverseTaskQueryRes pixverseTaskQueryRes = pixverseService.queryVideoTask(AiVideoPlatformEnum.PIXVERSE, aiVideo.getTaskId());
                    if (ObjectUtils.isNotEmpty(pixverseTaskQueryRes)) {
                        String status = pixverseTaskQueryRes.getStatus();
                        if (StringUtils.compare(status, AIVideoPlatformApiConstant.Pixverse.TaskStatus.SUCCESS) == 0) {
                            aiVideo.setPoster(pixverseTaskQueryRes.getPoster());
                            String fileUrl = uploadVideoUrlToOss(pixverseTaskQueryRes.getVideoUrl());
                            aiVideo.setVideoUrl(fileUrl);
                            aiVideo.setStatus(AiVideoStatusEnum.GENERATED_SUCCESSFULLY.getCode());
                        } else if (StringUtils.compare(status, AIVideoPlatformApiConstant.Pixverse.TaskStatus.FAILURE) == 0) {
                            aiVideo.setStatus(AiVideoStatusEnum.GENERATED_FAILED.getCode());
                        } else if (StringUtils.compare(status, AIVideoPlatformApiConstant.Pixverse.TaskStatus.IN_PROGRESS) == 0) {
                            aiVideo.setStatus(AiVideoStatusEnum.GENERATING.getCode());
                        }
                        aiVideo.setUpdateTime(Timer.currentTimestamp());
                        aiVideoMapper.updateById(aiVideo);
                    }
                } finally {
                    countDownLatch.countDown();
                }
            };
            taskExecutor.execute(task);
        } catch (Exception e) {
            log.debug("同步任务失败：{}", new Date(), e);
        }

    }

    private String uploadVideoUrlToOss(String videoUrl) {
        URL url = UrlBuilder.of(videoUrl).toURL();
        int count = 5;
        while (count-- > 0) {
            try {
                InputStream inputStream = url.openStream();
                String fileName = RandomStringUtils.randomAlphabetic(8) + ".mp4";
                ossUtil.uploadFile(OssUploadEnum.AI_VIDEO_UPLOAD, fileName, inputStream);
                String fileUrl = ossUtil.getFileUrl(OssUploadEnum.AI_VIDEO_UPLOAD, fileName);
                log.info("[video 同步任务] 视频上传成功：{}", fileUrl);
                return fileUrl;
            } catch (Exception e) {
                log.error("视频上传失败：{}", videoUrl, e);
            }
        }
        return videoUrl;
    }

}
